package meow

import org.hibernate.FetchMode

/**
 * フォロー関係を表す関連ドメイン
 * ※ 'Follower'って名前は予約語かなにかのため使う事が出来なかった。
 */
class Followers implements Serializable {
  static belongsTo = [
      owner: Account,     // フォローする側
      target: Account     // フォローされる側
  ]

  static mappings = {
    owner fetch: 'join'
    target fetch: 'join'
  }

  /** ページングしないで，お気に入りリストを返す   */
  static friendsList(username) {
    friendsList(username, -1).list
  }

  /** プロフィールに表示するお気に入りのショートリスト  */
  static friendsShortList(username) {
    withCriteria {
      owner { eq 'username', username }
      fetchMode 'target', FetchMode.JOIN
      maxResults 10     // ※10件っていう仕様だったので，やっつけです。
    }
  }

  /**
   * ページングしたお気に入りリストを返す
   * リストといっても[list, count]形式のmapを返す
   */
  static friendsList(username, offset) {
    [
        list: withCriteria {
          owner { eq 'username', username }
          // どうも検索条件にないとJOIN FETCHが有効にならないので，fetch modeを明示しておく
          fetchMode 'target', FetchMode.JOIN
          if (offset != -1) {
            firstResult offset
            maxResults Utils.MAX_RESULT
          }
        },
        count: withCriteria {
          projections { rowCount() }
          owner { eq 'username', username }
        }[0]    // rowCount() の戻り値は List なので，最初の要素を取り出す。
    ]
  }

  /** ページングしないで，お気に入られリストを返す   */
  static followersList(username) {
    followersList(username, -1).list
  }

  /**
   * ページングしたお気に入られリストを返す
   * リストといっても[list, count]形式のmapを返す
   */
  static followersList(username, offset) {
    [
        list: withCriteria {
          target { eq 'username', username }
          // どうも検索条件にないとJOIN FETCHが有効にならないので，fetch modeを明示しておく
          fetchMode 'owner', FetchMode.JOIN
          if (offset != -1) {
            firstResult offset
            maxResults Utils.MAX_RESULT
          }
        },
        count: withCriteria {
          projections { rowCount() }
          target { eq 'username', username }
        }[0]    // rowCount() の戻り値は List なので，最初の要素を取り出す。
    ]
  }
}
